package com.tweetgraph.domain;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Logger;

import org.slim3.datastore.Attribute;
import org.slim3.datastore.Model;

import twitter4j.Tweet;

import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.tweetgraph.util.TwitterSearchUtil;

@Model
public class BasicQuery implements TGQuery {

	private static Logger logger = Logger.getLogger(BasicQuery.class.getName());

	
	public static BasicQuery getInstance(Entity ent){
		BasicQuery query = null;
		
		if(ent != null && ent.getProperty("tag") != null){
			 query = new BasicQuery((String)ent.getProperty("name"),(String)ent.getProperty("tag"));
			 
			 if("Y".equals(ent.getProperty("considerOther"))){
				 query.countOther = true;
			 }else{
				 query.countOther=false;
			 }
			 
			 query.type = (String)ent.getProperty("resultType");
			 
			 /*
			  * Load the keywords
			  */
			 if(ent.getProperty("keywords") != null){
				 String[] csvKeyw = ((String)ent.getProperty("keywords")).split(",");
				 for(String word:csvKeyw){
					 query.addKeyWord(word);
				 }
			 }
		}
		
		return query;
	}
	
	
	public Entity getEntity(){
		
		Key key = KeyFactory.createKey("QueryResult", hashTag);
		Entity ent = new Entity(key);
		
		ent.setProperty("tag",hashTag);
		ent.setUnindexedProperty("name", name);
		ent.setUnindexedProperty("type","basic");
		ent.setUnindexedProperty("resultType",type);

		StringBuilder buffer = new StringBuilder();
		buffer.append("");
		for(String word:keyWordSet){
			buffer.append(word).append(",");
		}
		ent.setUnindexedProperty("keywords", buffer.toString());

		if(isCountOther()){
			ent.setUnindexedProperty("considerOther","Y");
		}else{
			ent.setUnindexedProperty("considerOther","N");
		}
		
		if(needToUpdateResults){
			ent.setUnindexedProperty("updateResults","Y");
		}else{
			ent.setUnindexedProperty("updateResults","N");
		}
		
		
		return ent;
	}

	/**
	 *
	 */
	private static final long serialVersionUID = 8022806160440826457L;

	@Attribute
	private String name;
	
	@Attribute(primaryKey = true) 
	private String hashTag;
	
	@Attribute
	private Set<String> keyWordSet = new TreeSet<String>();
	
	@Attribute
	private boolean needToUpdateResults = true;
	
	@Attribute
	private Map<String,Integer> keyWordOccurencesMap = new HashMap<String,Integer>();
	
	@Attribute
	private Set<Tweet> tweetSet = new TreeSet<Tweet>(new TweetComparator());
	
	@Attribute
	private boolean countOther = false;

	
	private String type;
	
	
	
	public String getType() {
		return type;
	}


	public void setType(String type) {
		this.type = type;
	}


	/**
	 *
	 * @param aName
	 * @param aHashTag
	 */
	public BasicQuery(String aName, String aHashTag){
		this.name = aName;
		this.hashTag = aHashTag.replace("#", "");
	}


	public void addKeyWord(String keyword){
		this.keyWordSet.add(keyword.toLowerCase());
	}

	
	public void addAllKeyWords(Set<String> words){
		for(String word:words){
			this.keyWordSet.add(word.toLowerCase());
		}
	}
	
	public boolean isCountOther() {
		return countOther;
	}


	public void setCountOther(boolean countOther) {
		this.countOther = countOther;
	}


	public void setNeedToUpdateResults(boolean needToUpdateResults) {
		this.needToUpdateResults = needToUpdateResults;
	}


	@Override
	public String getHashTag() {
		return this.hashTag;
	}

	@Override
	public Set<String> getKeywordSet() {
		return keyWordSet;
	}
	
	
	@Override
	public boolean getNeedToUpdateResults() {
		return needToUpdateResults;
	}

	@Override
	public long getLastProcessedTweet() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public String getName() {
		return this.name;
	}

	@Override
	public String getChartResultsInJSON() {
		StringBuilder bldr = new StringBuilder();
		int count = 0;

		bldr.append(name).append("{");
		for(String key:keyWordSet){
			bldr.append("\"").append(key).append("\":\"");
			bldr.append(keyWordOccurencesMap.get(key)==null?"0":""+keyWordOccurencesMap.get(key).intValue());
			bldr.append("\"");

			if(++count<keyWordSet.size()){
				bldr.append(",");
			}
		}
		bldr.append("}");

		return bldr.toString();
	}

	@Override
	public String getGeoResultsInJSON() {
		// TODO Auto-generated method stub
		return null;
	}


	@Override
	public Set<Tweet> getTweetSet() {
		return this.tweetSet;
	}


	public void addTweet(Tweet atweet){
		this.tweetSet.add(atweet);
	}
	
	
	public String toString(){
		StringBuilder bldr = new StringBuilder();
		logger.info("tag:"+hashTag);
		logger.info("keywords:"+keyWordSet.toString());
		logger.info("considerOther:"+this.countOther);
		logger.info("Num Tweets:"+this.tweetSet.size());
		
		return bldr.toString();
	}
	
}
